#pragma once

#include "noncopyable.h"
#include "InetAddress.h"
#include "Callbacks.h"
#include "Buffer.h"
#include "Timestamp.h"

#include <memory>
#include <string>
#include <atomic>

class Channel;
class EventLoop;
class Socket;

/**
 * TcpConnection 类, 用于管理 TCP 连接
 * TcpServer => Acceptor => 有一个新用户连接，通过accept函数拿到connfd
 * => TcpConnection 设置回调 => Channel => Poller => Channel的回调操作
 *
 * TcpConnection 类继承自 std::enable_shared_from_this<TcpConnection>，这意味着 TcpConnection 类
 * 的对象可以安全地使用 shared_from_this() 函数来获取指向自身的 std::shared_ptr。这对于在回调函数中传
 * 递 TcpConnection 对象的引用非常有用，因为可以确保在回调函数执行期间对象不会被销毁。
 */
class TcpConnection : noncopyable, public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop *loop,
                  const std::string &name,
                  int sockfd,
                  const InetAddress &localAddr, // 本地地址（服务器）
                  const InetAddress &peerAddr   // 对端地址（客户端）
                );
    ~TcpConnection();

    EventLoop *getLoop() const { return loop_; }  // 获取事件循环指针
    const std::string &name() const { return name_; } // 获取连接名字
    const InetAddress &localAddress() const { return localAddr_; } // 获取本地地址
    const InetAddress &peerAddress() const { return peerAddr_; }  // 获取对端地址

    bool connected() const { return state_ == kConnected; } // 判断连接是否已建立

    // 发送数据
    void send(const std::string &buf);
    // 关闭连接
    void shutdown();

    // 设置连接建立或断开时的回调函数
    void setConnectionCallback(const ConnectionCallback &cb)
    {
        connectionCallback_ = cb;
    }

    // 设置消息到达时的回调函数
    void setMessageCallback(const MessageCallback &cb)
    {
        messageCallback_ = cb;
    }

    // 设置消息发送完成时的回调函数
    void setWriteCompleteCallback(const WriteCompleteCallback &cb)
    {
        writeCompleteCallback_ = cb;
    }

    // 设置高水位标志和相应的回调函数
    void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t highWaterMark)
    {
        highWaterMarkCallback_ = cb;
        highWaterMark_ = highWaterMark;
    }

    // 设置连接关闭时的回调函数
    void setCloseCallback(const CloseCallback &cb)
    {
        closeCallback_ = cb;
    }

    // 连接建立
    void connectEstablished();
    // 连接销毁
    void connectDestroyed();

private:
    enum StateE
    {
        kDisconnected,
        kConnecting,
        kConnected,
        kDisconnecting
    };
    void setState(StateE state) { state_ = state; }  // 设置连接状态

    void handleRead(Timestamp receiveTime); // 读事件
    void handleWrite();  // 写事件
    void handleClose();  // 关闭事件
    void handleError();  // 错误事件

    void sendInLoop(const void *message, size_t len); // 在"事件循环" 中 "发送数据"
    void shutdownInLoop(); // 在"事件循环" 中 "关闭连接"

    EventLoop *loop_; // 这里绝对不是baseLoop， 因为TcpConnection都是在subLoop里面管理的
    const std::string name_; // 连接名称
    std::atomic_int state_;  // 连接状态
    bool reading_;  // 是否正在读取数据

    // 这里和Acceptor类似   Acceptor=》mainLoop    TcpConenction=》subLoop
    std::unique_ptr<Socket> socket_; 
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_; // 当前主机地址(本地地址)
    const InetAddress peerAddr_;  // 客户端地址

    ConnectionCallback connectionCallback_;       // 有新连接时的回调(连接建立或连接断开)
    MessageCallback messageCallback_;             // 有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完成以后的回调
    HighWaterMarkCallback highWaterMarkCallback_; // 高水位标志回调函数
    CloseCallback closeCallback_; // 连接关闭时的回调函数
    size_t highWaterMark_; // 高水位标志

    Buffer inputBuffer_;  // 接收数据的缓冲区
    Buffer outputBuffer_; // 发送数据的缓冲区
};